#include "dlist.h"
#include "mem.h"

z_list* z_list_alloc(void) 
{
  z_list *list;
  list = z_new0(z_list, 1);
  return list;
}

void z_list_destroy(z_list *list, z_destroy_notify destroy_func)
{
  z_list_node *node, *temp;
  
  node = list->head;
  while (node) {
    temp = node;
    node = node->next;
    if (destroy_func)
      destroy_func(temp->data);
    zfree(temp);
  }
}

void z_list_free(z_list *list)
{
  zfree(list);
}

static void internal_z_list_append(z_list *list, void *data, z_list_node *new_node)
{
  new_node->data = data;
  new_node->next = NULL;
  new_node->prev = list->tail;
  
  if (list->tail) 
    list->tail->next = new_node;
  else 
    list->head = new_node;
  list->tail = new_node;
  
}

void z_list_append(z_list *list, void *data)
{
  return internal_z_list_append(list, data, z_new(z_list_node, 1));
}

void z_list_append_chunk(z_list *list, void *data, z_mem_chunk *mem_chunk)
{
  return internal_z_list_append(list, data, z_mem_chunk_alloc(mem_chunk));
}

static void internal_z_list_prepend(z_list *list, void *data, z_list_node *new_node)
{
  new_node->data = data;
  new_node->next = list->head;
  new_node->prev = NULL;
  
  if (new_node->next)
    new_node->next->prev = new_node;
  else
    list->tail = new_node;
  list->head = new_node;
  
}

void z_list_prepend(z_list *list, void *data)
{
  return internal_z_list_prepend(list, data, z_new(z_list_node, 1));
}

void z_list_prepend_chunk(z_list *list, void *data, z_mem_chunk *mem_chunk)
{
  return internal_z_list_prepend(list, data, z_mem_chunk_alloc(mem_chunk));
}

#ifdef DEBUGL
#include <stdio.h>

int main() 
{
  z_list *tlst = z_list_alloc();
  
  z_list_append(tlst, "aaa");
  
  z_list_append(tlst, "bbb");
  z_list_prepend(tlst, "ccc");
  z_list_node *node = tlst->head;

  while (node) {
    printf("%s\t", node->data);
    node = node->next;
    
  }
  
  z_list_destroy(tlst, NULL);

  z_list_free(tlst);
  
  return 0;
}
#endif
